from sys import path

import requests
import re  # 正则表达式
import pprint
import json
from moviepy.editor import AudioFileClip, VideoFileClip
from bs4 import BeautifulSoup as bs
class SpiderBilibili():

    def __init__(self):

        self.headers = {
            # 防盗链 告诉服务器 我们请求的url网址是从哪里跳转过来的
            'referer': 'https://www.bilibili.com/a',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
        }


    def send_request(self,url):
        response = requests.get(url=url, headers=self.headers)
        return response

    def get_title(self,html_data):
        # 提取视频的标题
        soup = bs(html_data, 'lxml')
        title = soup.find_all(name='h1', attrs={"class": "video-title special-text-indent"})[0].get_text()
        return title
    def get_title1(self,html_data):
        # 提取视频的标题
        soup = bs(html_data, 'lxml')
        title = soup.find_all(name='title')[0].get_text()
        return title

    def get_video_data(self,html_data):
        """解析视频数据"""
        title=self.get_title(html_data=html_data)

        print(title)

        # 提取视频对应的json数据
        json_data = re.findall('<script>window\.__playinfo__=(.*?)</script>', html_data)[0]
        # print(json_data)  # json_data 字符串
        json_data = json.loads(json_data)
        pprint.pprint(json_data)

        # 提取音频的url地址
        audio_url = json_data['data']['dash']['audio'][0]['backupUrl'][0]
        print('解析到的音频地址:', audio_url)

        # 提取视频画面的url地址
        video_url = json_data['data']['dash']['video'][0]['backupUrl'][0]
        print('解析到的视频地址:', video_url)

        video_data = [title, audio_url, video_url]
        return video_data
    def get_video_data1(self,html_data):
        """解析视频数据"""
        title=self.get_title1(html_data=html_data)

        print(title)

        # 提取视频对应的json数据
        json_data = re.findall('<script>window\.*=(.*?)</script>', html_data)[0]
        # print(json_data)  # json_data 字符串
        json_data = json.loads(json_data)
        pprint.pprint(json_data)

        # 提取音频的url地址
        audio_url = json_data['data']['dash']['audio'][0]['backupUrl'][0]
        print('解析到的音频地址:', audio_url)

        # 提取视频画面的url地址
        video_url = json_data['data']['dash']['video'][0]['backupUrl'][0]
        print('解析到的视频地址:', video_url)

        video_data = [title, audio_url, video_url]
        return video_data

    def save_data(self,file_name, audio_url, video_url):
        # 请求数据
        print('正在请求音频数据')
        audio_data = self.send_request(audio_url).content
        print('正在请求视频数据')
        video_data = self.send_request(video_url).content
        with open(file_name + '.mp3', mode='wb') as f:
            f.write(audio_data)
            print('正在保存音频数据')
        with open(file_name + '.mp4', mode='wb') as f:
            f.write(video_data)
            print('正在保存视频数据')

    def save_data1(self, dir_path,file_name, audio_url, video_url):
        # 请求数据
        print('正在请求音频数据')
        audio_data = self.send_request(audio_url).content
        print('正在请求视频数据')
        video_data = self.send_request(video_url).content
        with open(dir_path+'//'+file_name + '.mp3', mode='wb') as f:
            f.write(audio_data)
            print('正在保存音频数据')
        with open(dir_path+'//'+file_name + '.mp4', mode='wb') as f:
            f.write(video_data)
            print('正在保存视频数据')

    def merge_data(self,video_name):
        print('视频合成开始:', video_name)
        audioclip = AudioFileClip(video_name + '.mp3')
        videoclip = VideoFileClip(video_name + '.mp4')
        # 3.获取视频和音频的时长
        video_time = videoclip.duration
        audio_time = audioclip.duration
        # 4.对视频或者音频进行裁剪
        if video_time > audio_time:
            # 视频时长>音频时长，对视频进行截取
            videoclip_new = videoclip.subclip(0, audio_time)
            audioclip_new = audioclip
        else:
            # 音频时长>视频时长，对音频进行截取
            videoclip_new = videoclip
            audioclip_new = audioclip.subclip(0, video_time)
        # 5.视频中加入音频
        video_with_new_audio = videoclip_new.set_audio(audioclip_new)
        # 6.写入到新的视频文件中
        video_with_new_audio.write_videofile("output.mp4",
                                             codec='libx264',
                                             audio_codec='aac',
                                             temp_audiofile='temp-video.m4a',
                                             remove_temp=True
                                             )
        print('视频合成结束:', video_name)
    def run(self,url):
        response = self.send_request(url)
        response.encoding = requests.utils.get_encodings_from_content(response.text)[0]
        html_data = response.text

        print('html', html_data)
        video_data = self.get_video_data(html_data)
        self.save_data(video_data[0], video_data[1], video_data[2])
        self.merge_data(video_data[0])
    def run1(self,url):
        response = self.send_request(url)
        response.encoding = requests.utils.get_encodings_from_content(response.text)[0]
        html_data = response.text

        print('html', html_data)
        video_data = self.get_video_data1(html_data)

url = 'https://www.bilibili.com/video/BV1bK421a7qG/?spm_id_from=333.1007.tianma.6-4-22.click'
url1='https://www.bilibili.com/bangumi/play/ep815163?spm_id_from=333.337.0.0&from_spmid=666.25.episode.0'

if __name__ == '__main__':
    spider=SpiderBilibili()
    spider.run1(url=url1)

